﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using JMT.Data;
using JMT.Data.Events;

namespace JMT.Controls.Elements
{
    /// <summary>
    /// InterfaceBox.xaml 的交互逻辑
    /// </summary>
    public partial class InterfaceBox : UserControl, IJBox, IEventHandler
    {
        private Point _lastLBCPos;
        private long _lastLBCTicks;

        private Data.JInterface _jmClass;

        public Data.JModel ClassModel
        {
            get
            {
                return _jmClass;
            }
        }

        public Data.JElement ElementModel { get; private set; }

        public ClassDiagram Diagram { get; set; }

        public InterfaceBox(Data.JInterface jInterface, Data.JElement jmElement)
        {
            InitializeComponent();

            //_ctlPanel.MouseLeftButtonDown += new MouseButtonEventHandler(_ctlPanel_MouseLeftButtonDown);
            this.SizeChanged += new SizeChangedEventHandler(InterfaceBox_SizeChanged);

            _jmClass = jInterface;
            ElementModel = jmElement;

            this.DataContext = _jmClass;

            _ctlPropContainer.Children.Clear();
            List<JProperty> propertyList = _jmClass.GetChildren<JProperty>();
            foreach (var item in propertyList)
            {
                JMTextBox textBox = new JMTextBox();
                textBox.SetBinding(TextBox.TextProperty, "Name");
                textBox.DataContext = item;
                _ctlPropContainer.Children.Add(textBox);
            }

            this._ctlMethodContainer.Children.Clear();
            List<JMethod> methodList = _jmClass.GetChildren<JMethod>();
            foreach (var item in methodList)
            {
                JMTextBox textBox = new JMTextBox();
                textBox.SetBinding(TextBox.TextProperty, "Name");
                textBox.DataContext = item;
                _ctlMethodContainer.Children.Add(textBox);
            }
        }

        private void JPropertyContainerUpdate(object sender, JUpdateEventArgs<JProperty> e)
        {
            _ctlPropContainer.Children.Clear();
            List<JProperty> propertyList = (_jmClass as IJContainer<JProperty>).ToList();
            foreach (var item in propertyList)
            {
                JMTextBox textBox = new JMTextBox();
                textBox.SetBinding(TextBox.TextProperty, "Name");
                textBox.DataContext = item;
                _ctlPropContainer.Children.Add(textBox);
            }
        }

        private void JMethodContainerUpdate(object sender, JUpdateEventArgs<JMethod> e)
        {
            this._ctlMethodContainer.Children.Clear();
            List<JMethod> methodList = (_jmClass as IJContainer<JMethod>).ToList();
            foreach (var item in methodList)
            {
                JMTextBox textBox = new JMTextBox();
                textBox.SetBinding(TextBox.TextProperty, "Name");
                textBox.DataContext = item;
                _ctlMethodContainer.Children.Add(textBox);
            }
        }

        void _ctlPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Point pos = e.GetPosition(_ctlPanel);
            if (_lastLBCPos.X == 0 && _lastLBCPos.Y == 0)
            {
                _lastLBCPos = pos;
                _lastLBCTicks = DateTime.Now.Ticks;
            }
            else
            {
                if (_lastLBCPos.X == pos.X && _lastLBCPos.Y == pos.Y)
                {
                    if (DateTime.Now.Ticks - _lastLBCTicks <= 2 * 10000000)
                    {
                        //MessageBox.Show("asd");
                        PopWindows.PopWindow pop = new PopWindows.PopWindow();
                        pop.Pop(new PopWindows.ClassWindow());

                        e.Handled = true;
                        _lastLBCPos.X = 0;
                        _lastLBCPos.Y = 0;
                    }
                    else
                    {
                        _lastLBCPos = pos;
                        _lastLBCTicks = DateTime.Now.Ticks;
                    }
                }
                else
                {
                    _lastLBCPos = pos;
                    _lastLBCTicks = DateTime.Now.Ticks;
                }
            }
        }

        public Rect GetRect()
        {
            return new Rect(
                Canvas.GetLeft(this),
                Canvas.GetTop(this),
                this.ActualWidth,
                this.ActualHeight);
        }

        /// <summary>
        ///  3  4  5
        ///  2     6
        ///  1  0  7
        /// </summary>
        /// <param name="direction"></param>
        /// <returns></returns>
        public Point GetLinkPos(int direction)
        {
            double x = Canvas.GetLeft(this);
            double y = Canvas.GetTop(this);
            double w = this.ActualWidth;
            double h = this.ActualHeight;
            if (direction == 0)
            {
                return new Point(x + w / 2, y + h);
            }
            else if (direction == 2)
            {
                return new Point(x, y + h / 2);
            }
            else if (direction == 4)
            {
                return new Point(x + w / 2, y);
            }
            else if (direction == 6)
            {
                return new Point(x + w, y + h / 2);
            }
            return new Point(x, y);
        }

        public Point GetCenterPos()
        {
            double x = Canvas.GetLeft(this);
            double y = Canvas.GetTop(this);
            double w = this.ActualWidth;
            double h = this.ActualHeight;
            return new Point(x + w / 2, y + h / 2);
        }

        public void SetPos(Point pos)
        {
            Canvas.SetLeft(this, pos.X);
            Canvas.SetTop(this, pos.Y);
            if (UpdateLayout != null)
            {
                UpdateLayout();
            }
        }

        void InterfaceBox_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (UpdateLayout != null)
            {
                UpdateLayout();
            }
        }


        public new event Action UpdateLayout;

        public void Handle(EventBase @event)
        {
            if (@event is AddModelEvent)
            {
                AddModelEvent addEvent = @event as AddModelEvent;
                IJContainer jContainer = addEvent.JContainer;
                JModel jModel = addEvent.JModel;

                if (jContainer == this._jmClass)
                {
                    JMTextBox textBox = new JMTextBox();
                    textBox.SetBinding(TextBox.TextProperty, "Name");
                    textBox.DataContext = jModel;
                    _ctlPropContainer.Children.Add(textBox);
                }
            }
        }
    }
}
